package cn.lan.generator.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.lan.generator.bean.EntityAttrInfo;
import cn.lan.generator.bean.EntityInfo;
import cn.lan.generator.bean.Module;
import cn.lan.generator.bean.ProjInfo;
import cn.lan.generator.service.CreateFile;
import cn.lan.generator.utils.ConfigUtil;
import cn.lan.generator.utils.Constant;
import cn.lan.generator.utils.FileUtil;
import cn.lan.generator.utils.StringUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lanping
 * @version 1.0
 * @date 2019-07-06
 **/
public class CreateEntityImpl implements CreateFile {

    private boolean hasField;

    public boolean isSQLKey(String columnName){
        boolean flag = false;
        for (String keyName:Constant.SQL_KEYS){
            if(keyName.equals(columnName.toLowerCase())){
                flag = true;
                break;
            }
        }
        return flag;
    }

    @Override
    public void writeFile(EntityInfo entityInfo, ProjInfo projInfo) throws Exception {
        String packageName = ConfigUtil.getEntityPackage(projInfo);

        String srcFilePath = FileUtil.getResourceRootDir(projInfo.isDebugModel())+Constant.TEMPLATE_ENTITY_PATH;

        String suffixPath = packageName.replaceAll("\\.", "\\\\") + "\\" + entityInfo.getEntityName() + Constant.FILE_SUFFIX_JAVA;
        String destFilePath = Constant.getFilePath(projInfo, Module.getModule(projInfo).getService(),  Constant.PathType.basePath, suffixPath);
        String idTypePackage = "\nimport com.baomidou.mybatisplus.annotation.IdType;";
        String entityAttributes= getEntityAttributes(entityInfo, entityInfo.getDbType());
        String entityFuncs= getFuncs(entityInfo.getEntityAttrs());

        String tableField = "";
        if(hasField){
            tableField = "\nimport com.baomidou.mybatisplus.annotation.TableField;";
            hasField = false;
        }
        String tableFieldStr = tableField;

        Map<String,String> map = new HashMap<String,String>(){
            {
                put("filePackageName",packageName);
                put("tableComment",entityInfo.getTableComment());
                put("projectAuthor",projInfo.getAuthor());
                put("upperEntityName", entityInfo.getEntityName());
                put("idTypePackage", idTypePackage);
                put("nowDate", DateUtil.today());
                put("entityAttributes", entityAttributes);
                put("entityFuncs", entityFuncs);
                put("tableField", tableFieldStr);
            }
        };
        FileUtil.copyFile(projInfo,srcFilePath, destFilePath, map);
    }

    /**
     * 获取属性
     * @param entityInfo
     * @return
     */
    private String getEntityAttributes(EntityInfo entityInfo,String dbType){
        StringBuffer sb = new StringBuffer();
        List<EntityAttrInfo> entityAttrs = entityInfo.getEntityAttrs();
        for(EntityAttrInfo entityAttrInfo:entityAttrs){
            sb.append("\t@ApiModelProperty(value = \""+entityAttrInfo.getColumnComment()+"\")\n");
            if(isSQLKey(entityAttrInfo.getColumnName())){
                if(entityAttrInfo.getColumnName().equals(entityInfo.getTablePrimaryKey())){
                    if(entityInfo.isAutoIncrement()){
                        if("Integer".equals(entityInfo.getPrimaryKeyType())){
                            if (Constant.DB_TYPE_MYSQL.equals(dbType)) {
                                sb.append("\t@TableId(value=\"`"+entityAttrInfo.getColumnName()+"`\",type = IdType.AUTO)\n");
                            }else if (Constant.DB_TYPE_DB2.equals(dbType)) {
                                sb.append("\t@TableId(value=\"'"+entityAttrInfo.getColumnName()+"'\",type = IdType.AUTO)\n");
                            } else if (Constant.DB_TYPE_SQLSERVER.equals(dbType)) {
                                sb.append("\t@TableId(value=\"'"+entityAttrInfo.getColumnName()+"'\",type = IdType.AUTO)\n");
                            }
                        }else if("Long".equals(entityInfo.getPrimaryKeyType())){
                            if (Constant.DB_TYPE_MYSQL.equals(dbType)) {
                                sb.append("\t@TableId(value=\"`"+entityAttrInfo.getColumnName()+"`\",type = IdType.AUTO)\n");
                            }else if (Constant.DB_TYPE_DB2.equals(dbType)) {
                                sb.append("\t@TableId(value=\"'"+entityAttrInfo.getColumnName()+"'\",type = IdType.AUTO)\n");
                            } else if (Constant.DB_TYPE_SQLSERVER.equals(dbType)) {
                                sb.append("\t@TableId(value=\"'"+entityAttrInfo.getColumnName()+"'\",type = IdType.AUTO)\n");
                            }
                        }
                    }else{
                        if (Constant.DB_TYPE_MYSQL.equals(dbType)) {
                            if("Integer".equals(entityInfo.getPrimaryKeyType()) || "Long".equals(entityInfo.getPrimaryKeyType())){
                                sb.append("\t@TableId(value=\"`"+entityAttrInfo.getColumnName()+"`\")\n");
                            }else{
                                sb.append("\t@TableId(value=\"`"+entityAttrInfo.getColumnName()+"`\",type = IdType.ASSIGN_ID)\n");
                            }
                        }else if (Constant.DB_TYPE_DB2.equals(dbType)) {
                            if("Integer".equals(entityInfo.getPrimaryKeyType()) || "Long".equals(entityInfo.getPrimaryKeyType())){
                                sb.append("\t@TableId(value=\"'"+entityAttrInfo.getColumnName()+"'\")\n");
                            }else{
                                sb.append("\t@TableId(value=\"'"+entityAttrInfo.getColumnName()+"'\",type = IdType.ASSIGN_ID)\n");
                            }
                        } else if (Constant.DB_TYPE_SQLSERVER.equals(dbType)) {
                            if("Integer".equals(entityInfo.getPrimaryKeyType()) || "Long".equals(entityInfo.getPrimaryKeyType())){
                                sb.append("\t@TableId(value=\"'"+entityAttrInfo.getColumnName()+"'\")\n");
                            }else{
                                sb.append("\t@TableId(value=\"'"+entityAttrInfo.getColumnName()+"'\",type = IdType.ASSIGN_ID)\n");
                            }
                        }
                    }
                }else{
                    hasField = true;
                    if (Constant.DB_TYPE_MYSQL.equals(dbType)) {
                        sb.append("\t@TableField(value=\"`"+entityAttrInfo.getColumnName()+"`\")\n");
                    }else if (Constant.DB_TYPE_DB2.equals(dbType)) {
                        sb.append("\t@TableField(value=\"'"+entityAttrInfo.getColumnName()+"'\")\n");
                    } else if (Constant.DB_TYPE_SQLSERVER.equals(dbType)) {
                        sb.append("\t@TableField(value=\"'"+entityAttrInfo.getColumnName()+"'\")\n");
                    }
                }
            }else{
                if(entityAttrInfo.getColumnName().equals(entityInfo.getTablePrimaryKey())){
                    if(entityInfo.isAutoIncrement()){
                        if("Integer".equals(entityInfo.getPrimaryKeyType())){
                            sb.append("\t@TableId(type = IdType.AUTO)\n");
                        }else if("Long".equals(entityInfo.getPrimaryKeyType())){
                            sb.append("\t@TableId(type = IdType.AUTO)\n");
                        }
                    }else{
                        //sb.append("\t@TableId\n");
                        sb.append("\t@TableId(type = IdType.ASSIGN_ID)\n");
                    }
                }
            }
            sb.append("\tprivate "+entityAttrInfo.getAttrType()+" "+entityAttrInfo.getAttrName()+";\n\n");
        }
        return sb.toString();
    }

    /**
     * 设置get与set方法
     *
     * @param entityAttrInfos
     * @return
     */
    private String getFuncs(List<EntityAttrInfo> entityAttrInfos) {
        StringBuffer sb = new StringBuffer();
        for (EntityAttrInfo entityAttrInfo:entityAttrInfos){
            String lowerName = entityAttrInfo.getAttrName();
            String upperName = StringUtil.toUpperCaseFirstOne(entityAttrInfo.getAttrName());
            sb.append("\tpublic "+entityAttrInfo.getAttrType()+" get"+upperName+"() {\n");
            sb.append("\t\treturn "+lowerName+";\n");
            sb.append("\t}\n\n");

            sb.append("\tpublic void set"+upperName+"("+entityAttrInfo.getAttrType()+" " + lowerName+") { \n");
            sb.append("\t\tthis."+lowerName+" = "+ lowerName+";\n");
            sb.append("\t}\n\n");
        }
        return sb.toString();
    }
}
